#pragma once
#include <unordered_map>
#define _USE_MATH_DEFINES
#include <algorithm>
#include <cv.h>
#include <highgui.h>
#include <cmath>
#include "mytype.h"
#include "ALBPPattern.h"

class AlbpAnalysis
{
public:
	AlbpAnalysis(void);
	AlbpAnalysis(int pNumPoints, int pRadius);
	~AlbpAnalysis(void);
    std::vector<double>& AnalyzeData(SeedNode *pSeedLoc, int pWidthDim);
	void SetNeighborhoodSystem(int* pNeighbSystem, int pNeighbSysWidth, int pNeighbSysHeight);
    void InitAnalyzer(const cv::Mat* pImgData, int pWidthStep, int pNumChannels, int pTopN);
private:
	/* Member variables */
	// number of points to analyze in each neighborhood
	int m_iNumPoints;	
	// radius in pixels between center pixel and each neighborhood point 
	int m_iRadius;
	// an unordered map that contains all the albp patterns generated from the input data array
	std::tr1::unordered_map <int, ALBPPattern> m_umPatterns;
	// the image being analyzed
    const cv::Mat* m_ImgData;
	// the matrix describing the spatial distribution of the dominant patterns within the input data matrix
	int* m_SidpMatrix;
	// the neighborhood system (structuring element) used to compute the Gray Level Aura Matrix
	int* m_NeighborSystem;
    // aligned step size in bytes for one row of data
    int m_iWidthStep;
    // number of channels for the image data being processed
    int m_iNumChannels;
	// the width dimension of the neighborhood system
	int m_iNeighbSysWidth;
	// the height dimension of the neighborhood system
	int m_iNeighbSysHeight;
    // Number of most frequently occurring ALBP patterns to use in feature set
    int m_iTopN;
	// the starting x coordinate of the area in the data matrix that is to be analyzed
    int m_iRegionStartX;
	// the starting y coordinate of the area in the data matrix that is to be analyzed
    int m_iRegionStartY;
    // the size of the dimension of the region being analyzed
    int m_iRegionSize;
    // the width of the entire image
	int m_iImgWidth;
    // the height of the entire image
	int m_iImgHeight;
	/* end Member variables */

	int  AssignGroup(int pLabel);
	int  AssignLabel(int pRow, int pCol);
	int  CircularLeftShift(int pValue, int pNumBits);
	void ComputeGLAM(int* pGlam);
	int  ComputeGLAMMeasureAt(int i, int j, int pCenterY, int pCenterX);
	void ComputeSIDP();
	int  InterpolateValue(double pRow, double pCol);
	void UpdatePattern(int pGroup, int pRow, int pCol);
};
